package ws

import (
	"django_blog_gin/internal/svc"
	"django_blog_gin/internal/utils"
	"django_blog_gin/internal/ws"
	"encoding/json"
	"log"
	"net/http"
	"strconv"
	"strings"
	"time"

	"github.com/gin-gonic/gin"
	"github.com/gorilla/websocket"
)

var upgrader = websocket.Upgrader{
	ReadBufferSize:  1024,
	WriteBufferSize: 1024,
	CheckOrigin: func(r *http.Request) bool {
		// 允许所有来源的WebSocket连接
		return true
	},
}

// WebSocket处理器
type WSHandler struct {
	manager *ws.Manager
	svcCtx  *svc.ServiceContext
}

// 创建新的WebSocket处理器
func NewWSHandler(svcCtx *svc.ServiceContext) *WSHandler {
	// 直接使用服务上下文中已创建的Manager
	return &WSHandler{
		manager: svcCtx.WSManager,
		svcCtx:  svcCtx,
	}
}

// 处理WebSocket连接请求
func (h *WSHandler) Connect(c *gin.Context) {
	// 从URL参数或请求头获取token
	var tokenString string

	// 尝试从Authorization头获取
	authHeader := c.GetHeader("Authorization")
	if authHeader != "" && strings.HasPrefix(authHeader, "Bearer ") {
		tokenString = authHeader[len("Bearer "):]
	} else {
		// 从URL参数获取token
		tokenString = c.Query("token")
		if tokenString == "" {
			c.JSON(http.StatusUnauthorized, gin.H{"error": "Authorization header or token parameter required"})
			return
		}
	}

	// 解析JWT
	tokenMap, err := utils.ParseJwtToken(tokenString)
	if err != nil {
		c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid or expired token"})
		return
	}

	// 升级HTTP连接到WebSocket连接
	conn, err := upgrader.Upgrade(c.Writer, c.Request, nil)
	if err != nil {
		log.Printf("WebSocket升级连接失败: %v, 客户端IP: %s", err, c.ClientIP())
		return
	}

	// 使用JWT中的用户ID和用户名
	userID := strconv.Itoa(tokenMap.UserId)
	username := tokenMap.Username

	// 创建新的客户端
	client := &ws.Client{
		ID:       userID,
		Username: username, // 设置用户名
		Conn:     conn,
		Send:     make(chan []byte, 256),
		Manager:  h.manager,
	}

	// 注册客户端
	h.manager.Register <- client

	// 启动读写goroutine
	go client.Write()
	go client.Read()
}

// 发送消息API（供非WebSocket客户端使用）
func (h *WSHandler) SendMessage(c *gin.Context) {
	var msg ws.Message
	if err := c.ShouldBindJSON(&msg); err != nil {
		c.JSON(400, gin.H{"error": "参数错误"})
		return
	}

	msg.Timestamp = time.Now().Unix()

	// 将消息转换为JSON
	messageJSON, err := json.Marshal(msg)
	if err != nil {
		c.JSON(500, gin.H{"error": "消息序列化失败"})
		return
	}

	// 发送消息
	if msg.Recipient != "" {
		h.manager.SendPrivate <- messageJSON
	} else {
		h.manager.Broadcast <- messageJSON
	}

	c.JSON(200, gin.H{"code": 0, "msg": "发送成功"})
}
